package com.qf.business.search.service.impl;

import com.qf.business.search.entity.CourseEsEntity;
import com.qf.business.search.entity.SearchParam;
import com.qf.business.search.service.ISearchService;
import lombok.extern.slf4j.Slf4j;
import org.elasticsearch.index.query.QueryBuilder;
import org.elasticsearch.index.query.QueryBuilders;
import org.elasticsearch.search.fetch.subphase.highlight.HighlightBuilder;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Sort;
import org.springframework.data.elasticsearch.core.ElasticsearchRestTemplate;
import org.springframework.data.elasticsearch.core.IndexOperations;
import org.springframework.data.elasticsearch.core.SearchHit;
import org.springframework.data.elasticsearch.core.SearchHits;
import org.springframework.data.elasticsearch.core.document.Document;
import org.springframework.data.elasticsearch.core.query.HighlightQuery;
import org.springframework.data.elasticsearch.core.query.NativeSearchQuery;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;

import java.util.ArrayList;
import java.util.List;

/**
 * author Ken
 * create_time 2022/11/30
 */
@Service
@Slf4j
public class SearchServiceImpl implements ISearchService {

    @Autowired
    private ElasticsearchRestTemplate elasticsearchRestTemplate;

    @Override
    public boolean createIndex() {
        IndexOperations indexOperations = elasticsearchRestTemplate.indexOps(CourseEsEntity.class);
        if (indexOperations.exists()) {
            log.debug("[create es index] ES索引已经存在！");
            return true;
        }

        log.debug("[create es index] 创建ES索引库成功！");
        //创建索引库
        indexOperations.create();
        //创建映射关系
        Document document = indexOperations.createMapping();
        indexOperations.putMapping(document);
        return true;
    }


    @Override
    public CourseEsEntity insertCourse(CourseEsEntity esEntity) {
        return elasticsearchRestTemplate.save(esEntity);
    }

    /**
     * 进行业务搜索
     * @param searchParam
     * @return
     */
    @Override
    public List<CourseEsEntity> search(SearchParam searchParam) {

        //构建查询的条件
        QueryBuilder queryBuilder = QueryBuilders.multiMatchQuery(searchParam.getKeyword())
                .field("cname", 5)
//                .field("cname.pinyin", 0.5f)
                .field("info", 3);

        NativeSearchQuery query = new NativeSearchQuery(queryBuilder);

        //设置分页
        if (searchParam.getPageNum() < 1) searchParam.setPageNum(1);
        if (searchParam.getPageSize() < 1) searchParam.setPageSize(20);
        query.setPageable(PageRequest.of((searchParam.getPageNum() - 1) * searchParam.getPageSize(), searchParam.getPageSize())); //limit (page - 1) * pagesize, pagesize

        //处理排序
        if (searchParam.getSortType() != null) {
            switch (searchParam.getSortType()) {
                case 2:
                    //按照价格排序
                    query.addSort(Sort.by(new Sort.Order(
                            searchParam.getSortFlag() == 0 ? Sort.Direction.ASC : Sort.Direction.DESC, "price")));
                    break;
            }
        }

        //设置搜索的高亮
        query.setHighlightQuery(new HighlightQuery(
                new HighlightBuilder()
                        .field("cname")
                        .preTags("<a class='highlight'>")
                        .postTags("</a>")
        ));

        //进行搜索
        SearchHits<CourseEsEntity> results = elasticsearchRestTemplate.search(query, CourseEsEntity.class);
        //处理结果集
        List<SearchHit<CourseEsEntity>> courses = results.getSearchHits();
        log.debug("[search course] 课程搜索的结果数量 - {}", results.getTotalHits());

        List<CourseEsEntity> courseEsEntityList = new ArrayList<>();
        //循环处理每个课程对象
        for (SearchHit<CourseEsEntity> course : courses) {
            //获得课程对象
            CourseEsEntity content = course.getContent();
            System.out.println("相关度：" + course.getScore() + " 结果：" + content);
            //添加的返回的集合中
            courseEsEntityList.add(content);
            //处理当前课程的高亮
            List<String> cname = course.getHighlightField("cname");
            if (!CollectionUtils.isEmpty(cname)) {
                //说明有高亮
                content.setCname(cname.get(0));
            }
        }
        return courseEsEntityList;
    }
}
